<?php

namespace Core\Mvc;

use Phalcon\Mvc\MongoCollection;
use MongoDB\BSON\ObjectID;
use Phalcon\Mvc\Collection\Exception;
use Phalcon\Di;

class Collection extends MongoCollection
{
    protected $_relationships;
    protected $_relationshipsData = [];

    protected function hasMany($data)
    {
        $className = $data['model'] . '::find';
        if (isset($data['obid']) && $data['obid'] === true) {
            $data = $className([
                'conditions' => [
                    $data['modelKey'] => new ObjectID($this->{$data['key']}),
                ]
            ]);
        } else {
            $data = $className([
                'conditions' => [
                    $data['modelKey'] => $this->{$data['key']},
                ]
            ]);
        }
        return $data;
    }

    protected function hasOne($data)
    {
        $className = $data['model'] . '::findFirst';
        if (isset($data['obid']) && $data['obid'] === true) {
            $data = $className([
                'conditions' => [
                    $data['modelKey'] => new ObjectID($this->{$data['key']}),
                ]
            ]);
        } else {
            $data = $className([
                'conditions' => [
                    $data['modelKey'] => $this->{$data['key']},
                ]
            ]);
        }
        return $data;
    }

    protected function belongsTo($data)
    {
        return $this->hasOne($data);
    }

    protected function hasManyToMany($data)
    {
        return $this->hasMany($data);
    }

    public function __get(string $propertyName)
    {
        //获取关联模型数据
        if ($this->getId() && isset($this->_relationships[$propertyName]) && isset($this->{$this->_relationships[$propertyName]['key']})) {
            if (isset($this->_relationshipsData[$propertyName])) {
                return $this->_relationshipsData[$propertyName];
            }

            $this->_relationshipsData[$propertyName] = $this->{$this->_relationships[$propertyName]['type']}($this->_relationships[$propertyName]);
            return $this->_relationshipsData[$propertyName];
        }

        //获取注入服务
        $dependencyInjector = $this->_dependencyInjector;
        if (is_object($dependencyInjector) === false) {
            $dependencyInjector = Di::getDefault();

            if (is_object($dependencyInjector) === false) {
                throw new Exception('A dependency injector object is required to access the application services');
            }
        }

        //Fallback to the PHP userland if the cache is not available
        if ($dependencyInjector->has($propertyName) === true) {
            $service = $dependencyInjector->getShared($propertyName);
            //$this->$propertyName = $service;
            return $service;
        }

        //Dependency Injector
        if ($propertyName === 'di') {
            $this->di = $dependencyInjector;
            return $dependencyInjector;
        }

        //Accessing the persistent property will create a session bag in any class
        //A notice is shown if the property is not defined and isn't a valid service
        trigger_error('Access to undefined property ' . $propertyName, \E_USER_WARNING);
    }
}